#pragma once
#include <atomic>
#include <chrono>
#include <shared_mutex>
#include <stdlib.h>
#include <vector>
#define vecnum 128
inline uint64_t getNowTimeNsChrono()
{
	auto val = std::chrono::system_clock::now();
	return std::chrono::duration_cast<std::chrono::nanoseconds>(val.time_since_epoch()).count();
}
template<typename T>
class threadfreevec {
public:
	void push_back(T res) {
		srand(getNowTimeNsChrono());
		auto vecindex = rand() % vecnum;
		sou[vecindex].lock.lock();
		sou[vecindex].sou.push_back(res);
		sou[vecindex].lock.unlock();
		vecsize[vecindex]++;
		size++;
	}
	T randget() {
		srand(getNowTimeNsChrono());
		unsigned long long vecindex;
		while (true) {
			vecindex = rand() % vecnum;
			unsigned long long secsize = vecsize[vecindex];
			if (secsize == 0) {
				continue;
			}
			else {
				break;
			}
		}
		auto index = rand() % vecsize[vecindex];
		sou[vecindex].lock.lock_shared();
		T tmp = sou[vecindex].sou[index];
		sou[vecindex].lock.unlock_shared();
		return tmp;
	}
	bool find(T res) {
		bool result = false;
		for (int i = 0; i < vecnum; i++) {
			sou[i].lock.lock_shared();
			for (int j = 0; j < vecsize[i]; j++) {
				if (sou[i].sou[j] == res) {
					result = true;
					break;
				}
			}
			sou[i].lock.unlock_shared();
			if (result) {
				break;
			}
		}
		return result;
	}
	int getsize() {
		return size;
	}
	std::atomic<unsigned long long>* getsizeptr() {
		return &size;
	}
	T delrand() {
		srand(getNowTimeNsChrono());
		auto vecindex = rand() % vecnum;
		sou[vecindex].lock.lock();
		auto index = rand() % vecsize[vecindex];
		T tmp = sou[vecindex].sou[index];
		sou[vecindex].sou.erase(sou[vecindex].sou.begin() + index);
		sou[vecindex].lock.unlock();
		vecsize[vecindex]--;
		return tmp;
	}
	void delitem(T res) {
		for (int i = 0; i < vecnum; i++) {
			sou[i].lock.lock_shared();
			for (int j = 0; j < vecsize[i]; j++) {
				if (sou[i].sou[j] == res) {
					sou[i].lock.unlock_shared();
					sou[i].lock.lock();
					sou[i].sou.erase(sou[i].sou.begin() + j);
					sou[i].lock.unlock();
				}
			}
			sou[i].lock.unlock_shared();
		}
	}
private:
	struct sou
	{
		std::shared_mutex lock;
		std::vector<T> sou;
	};
	std::atomic<unsigned long long> vecsize[vecnum];
	std::atomic<unsigned long long> size = 0;
	sou sou[vecnum];

};